
#region copyright notice
/* ====================================================================
 * The UncleGED Open Source Software License
 *
 * Copyright (c) 1999-2009 D. M. DeBacker. All rights reserved.
 * http://gatheringleaves.org/uged
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. Products derived from this software may not be called "UncleGED",
 *    nor may "UncleGED" appear in their name, without prior written
 *    permission of D. M. DeBacker.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL D. M. DEBACKER BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Diagnostics;
using log4net;

using UncleGED;
using UncleGED.Utils;
using UncleGED.Application;

namespace UGed
{
   public partial class BuildPages : Form
   {
      // These are the Win32 error code for file not found or access denied.
      const int ERROR_FILE_NOT_FOUND = 2;
      const int ERROR_ACCESS_DENIED = 5;

      GedReader m_gedreader;
      bool m_DidCancel = false;
      UGedProject m_UGProj = new UGedProject();
      LocalApplication m_localSettings = new LocalApplication();
      log4net.ILog _logger;
      bool m_pageProcessing = false;

      public BuildPages()
      {
         InitializeComponent();
      }

      public BuildPages(UGedProject ugProj, LocalApplication localSettings, log4net.ILog logger)
      {

         InitializeComponent();
         m_UGProj = ugProj;
         m_localSettings = localSettings;
         _logger = logger;
         m_gedreader = new GedReader(m_UGProj, m_localSettings, m_UGProj.GedComFile);
         m_gedreader.StatusMessage += new StatusMessageEventHandler(GedReader_StatusMessage);

      }

      private void GedReader_StatusMessage(object sender, StatusMessageArgs e)
      {
         this.lblStatus.Text = e.Message;

         if (e.IsProgress == true)
         {
            pbProgress.Maximum = (int)e.CountTotal;
            pbProgress.Value = (int)e.Counter;
         }

         Application.DoEvents();

         if (e.IsError == true)
         {
            MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
         }

         if (e.IsProgress == false && e.IsError == false && e.IsDebug == false)
         {
            _logger.Info(e.Message);
         }

         if (e.IsError == true)
         {
            _logger.Error(e.Message);
         }

         if (e.IsDebug == true)
         {
            _logger.Debug(e.Message);
         }
      }

      private bool DoProcessing()
      {
         m_pageProcessing = true;

         bool bRet = false;
         bool procOkay = false;
         string fName = m_UGProj.GedcomPath + "\\" + m_UGProj.GedComFile;

         this.picFamilyPages.Visible = false;
         this.lblTitle.Text = "Data Processing";
         this.lblDescription.Text = "Please wait while UncleGED processes your data...";
         pbProgress.Visible = false;

         m_gedreader = new GedReader(m_UGProj, m_localSettings, m_UGProj.GedComFile);
         m_gedreader.StatusMessage += new StatusMessageEventHandler(GedReader_StatusMessage);

         //process the data
         this.picFamilyPages.Visible = true;
         this.picFamilyPages.Image = global::UGed.Properties.Resources.FINDFILE16;
         this.lblTitle.Text = "Processing GEDCOM";
         this.lblDescription.Text = "Reading " + UncleGED.Utils.Tools.LongDirFix(fName, 75);
         pbProgress.Visible = true;

         procOkay = m_gedreader.ProcessGedComFile(fName, true);

      //SKIP_READ_FILE:
         if (procOkay)
         {
            this.picFamilyPages.Visible = true;
            pbProgress.Visible = false;

            if (m_UGProj.DoDateEstimation == true)
            {
               m_gedreader.EstimateBirthDates();
               m_gedreader.SaveEstimatedDatesList();
            }

            if (m_UGProj.ExcludeLivingIndividualsAfterBirthCutOff == true)
            {
               m_gedreader.ExcludeLivingIndividuals();
            }

            this.lblTitle.Text = "Creating Web Pages";
				this.lblDescription.Text = "Creating web pages from data found in " + UncleGED.Utils.Tools.LongDirFix(fName, 75);
            this.picFamilyPages.Image = global::UGed.Properties.Resources.FINDCOMP_00;
            //write out the HTML files
            m_gedreader.SaveAsHTM();

            bRet = true;
         }
         else
         {
            bRet = false;
         }

         this.picFamilyPages.Visible = false;
         this.pbProgress.Visible = false;

         m_pageProcessing = false;

         return bRet;
      }

      private void btnStartBuild_Click(object sender, EventArgs e)
      {
         this.btnStartBuild.Enabled = false;
         this.txtStats.Visible = false;
         this.btnViewPages.Enabled = false;
         string msg;

         if (this.DoProcessing() == true)
         {
            if (m_DidCancel == false)
            {
               msg = GetStats();
               this.txtStats.Text = msg;
               this.btnViewPages.Enabled = true;
               this.txtStats.Visible = true;
               this.txtStats.BringToFront();
               this.lblTitle.Text = "Done!";
               this.lblDescription.Text = "Click View Pages to view pages in browser or Cancel to close this window";
            }
            else
            {
               this.txtStats.Visible = false;
               this.btnViewPages.Enabled = false;
               this.lblTitle.Text = "Action Cancelled";
               this.lblDescription.Text = "The action was cancelled by the user. Click the OK button to quit or click the Back button to start over.";
            } this.btnViewPages.Enabled = true;
         }
         this.btnStartBuild.Enabled = true;
      }


      private void btnCancel_Click(object sender, EventArgs e)
      {
         if (m_pageProcessing == true)
         {
            m_gedreader.Cancel = true;
            m_DidCancel = true;
         }
         else
         {
            this.Close();
         }
      }

      private string GetStats()
      {
         string msg = "";
         float sngSources = 0F;
         float sngNotes = 0F;
         int iMissBirthDate = 0;
         int iMissBirthPlace = 0;
         int iPartBirthdate = 0;
         int iMissDeathDate = 0;
         int iPartDeathDate = 0;
         int iMissDeathPlace = 0;
         int NumInds = 0;
         int iCnt = 0;
         float sngStat = 0F;

         StringFunctions sf = new StringFunctions();

         msg = "Statistics for " + this.m_UGProj.GedComFile + System.Environment.NewLine;
         msg += "Num Indviduals: " + m_gedreader.MyIndividuals.Count.ToString().Trim() + System.Environment.NewLine;
         msg += "Num Families: " + m_gedreader.MyFamilies.Count.ToString().Trim() + System.Environment.NewLine;
         msg += "Num Notes: " + m_gedreader.MyNotes.Count.ToString().Trim() + System.Environment.NewLine;
         msg += "Num Sources: " + m_gedreader.MySources.Count.ToString().Trim() + System.Environment.NewLine;

         msg += System.Environment.NewLine;

         if (m_gedreader.MyNotes.Count > 0)
         {
            sngNotes = (float)m_gedreader.MyNotes.Count / (float)m_gedreader.MyIndividuals.Count;
            msg += "Notes/Inds: " + sf.FormatSingle(sngNotes, "#,##0.00;;;Nil") + System.Environment.NewLine;
         }
         else
            msg += "Notes/Inds: 0" + System.Environment.NewLine;

         if (m_gedreader.MySources.Count > 0)
         {
            sngSources = (float)m_gedreader.MySources.Count / (float)m_gedreader.MyIndividuals.Count;
            msg += "Sources/Inds: " + sf.FormatSingle(sngSources, "#,##0.00;;;Nil") + System.Environment.NewLine;
         }
         else
            msg += "Sources/Inds: 0" + System.Environment.NewLine;

         msg += System.Environment.NewLine;

         NumInds = m_gedreader.MyIndividuals.Count;

         if (NumInds > 0)
         {
            for (iCnt = 0; iCnt < NumInds; iCnt++)
            {
               if (m_gedreader.MyIndividuals[iCnt].BirthDateText.Trim() == "")
                  iMissBirthDate++;
               if (sf.IsDate(m_gedreader.MyIndividuals[iCnt].BirthDateText) == false && m_gedreader.MyIndividuals[iCnt].BirthDateText.Trim() != "")
                  iPartBirthdate++;
               if (m_gedreader.MyIndividuals[iCnt].DeathDateText.Trim() == "")
                  iMissDeathDate++;
               if (sf.IsDate(m_gedreader.MyIndividuals[iCnt].DeathDateText) == false && m_gedreader.MyIndividuals[iCnt].DeathDateText.Trim() != "")
                  iPartDeathDate++;
               if (m_gedreader.MyIndividuals[iCnt].BirthPlace.Trim() == "")
                  iMissBirthPlace++;
               if (m_gedreader.MyIndividuals[iCnt].DeathPlace.Trim() == "")
                  iMissDeathPlace++;
            }

            sngStat = (float)iMissBirthDate / (float)m_gedreader.MyIndividuals.Count;
            msg += "Missing Birth Dates: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
            sngStat = (float)iPartBirthdate / (float)m_gedreader.MyIndividuals.Count;
            msg += "Partial Birth Dates: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
            sngStat = (float)iMissBirthPlace / (float)m_gedreader.MyIndividuals.Count;
            msg += "Missing Birth Place: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
            sngStat = (float)iMissDeathDate / (float)m_gedreader.MyIndividuals.Count;
            msg += "Missing Death Dates: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
            sngStat = (float)iPartDeathDate / (float)m_gedreader.MyIndividuals.Count;
            msg += "Partial Death Dates: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
            sngStat = (float)iMissDeathPlace / (float)m_gedreader.MyIndividuals.Count;
            msg += "Missing Death Place: " + sf.FormatSingle(sngStat, "0.00%") + System.Environment.NewLine;
         }

         return msg;

      }

      private void btnViewPages_Click(object sender, EventArgs e)
      {
         this.Close(); //DoViewPages();
      }

      private void DoViewPages()
      {
         Process myProcess = new Process();

         try
         {

            if (m_UGProj.PageFileExtension == 0)
               myProcess.StartInfo.FileName = m_UGProj.HtmlPath + "\\index.html";
            else
               myProcess.StartInfo.FileName = m_UGProj.HtmlPath + "\\index.htm";

            myProcess.StartInfo.CreateNoWindow = true;
            myProcess.Start();
            this.Close();
         }
         catch (Win32Exception ex)
         {
            if (ex.NativeErrorCode == ERROR_FILE_NOT_FOUND)
            {
               MessageBox.Show(String.Format(ex.Message + ". Check the HTML path setting."));
            }

            else if (ex.NativeErrorCode == ERROR_ACCESS_DENIED)
            {
               // Note that if your word processor might generate exceptions
               // such as this, which are handled first.
               MessageBox.Show(String.Format(ex.Message +
                  ". You do not have permission to view this file."));
            }
         }
         catch (Exception ex1)
         {
            MessageBox.Show(String.Format(ex1.Message));
         }

      }


   }
}